﻿using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using NapazEngine.Framework.GameObjects;
using NapazEngine.Utilities.Data;

namespace NapazEngine.Framework.Controls
{
    /// <summary>
    /// This class automatically handles the updating of controller and keyboard states.
    /// It does also handle the mapping of game actions to controls
    /// </summary>
    public class ControlsManager: GameComponent
    {
        //PC input states
        private KeyboardState currentKeyboardState;
        private KeyboardState previousKeyboardState;
        private MouseState currentMouseState;
        private MouseState previousMouseState;

        //Xbox input states
        private GamePadState[] currentControllerStates;
        private GamePadState[] previousControllerStates;

        //Controls for PC
        private Dictionary<Player.Action, Keys> controls;
        public Dictionary<Player.Action, Keys> Controls { get { return controls; } }

        public ControlsManager(Game game) : base(game)
        {
            controls = new Dictionary<Player.Action, Keys>();
            SetDefaultControls();
        }

        public ControlsManager(Game game, Dictionary<Player.Action, Keys> controls) : base(game)
        {
            this.controls = controls;
        }

        public override void Initialize()
        {
            currentControllerStates = new GamePadState[4];
            previousControllerStates = new GamePadState[4];

            base.Initialize();
        }

        private void SetDefaultControls()
        {
            controls.Add(Player.Action.MoveUp, Defaults.DEFAULT_MOVE_UP_KEY);
            controls.Add(Player.Action.MoveDown, Defaults.DEFAULT_MOVE_DOWN_KEY);
            controls.Add(Player.Action.MoveLeft, Defaults.DEFAULT_MOVE_LEFT_KEY);
            controls.Add(Player.Action.MoveRight, Defaults.DEFAULT_MOVE_RIGHT_KEY);
            controls.Add(Player.Action.Jump, Defaults.DEFAULT_JUMP_KEY);
            controls.Add(Player.Action.Shoot, Defaults.DEFAULT_SHOOT_KEY);
            controls.Add(Player.Action.Quit, Defaults.DEFAULT_QUIT_KEY);
        }

        public override void Update(GameTime gameTime)
        {
#if !XBOX360
            //store our old PC input states
            previousKeyboardState = currentKeyboardState;
            previousMouseState = currentMouseState;

            //retrieve the new PC input states
            currentKeyboardState = Keyboard.GetState();
            currentMouseState = Mouse.GetState();
#else
            //store our old Xbox input states
            previousControllerStates[0] = currentControllerStates[0];
            previousControllerStates[1] = currentControllerStates[1];
            previousControllerStates[2] = currentControllerStates[2];
            previousControllerStates[3] = currentControllerStates[3];

            //retrieve the new Xbox input states
            currentControllerStates[0] = GamePad.GetState(PlayerIndex.One);
            currentControllerStates[1] = GamePad.GetState(PlayerIndex.Two);
            currentControllerStates[2] = GamePad.GetState(PlayerIndex.Three);
            currentControllerStates[3] = GamePad.GetState(PlayerIndex.Four);
#endif

            base.Update(gameTime);
        }

        public KeyboardState CurrentKeyboardState
        {
            get { return currentKeyboardState; }
        }

        public KeyboardState PreviousKeyboardState
        {
            get { return previousKeyboardState; }
        }

        public MouseState CurrentMouseState
        {
            get { return currentMouseState; }
        }

        public MouseState PreviousMouseState
        {
            get { return previousMouseState; }
        }

        public GamePadState[] CurrentControllerStates
        {
            get { return currentControllerStates; }
        }

        public GamePadState[] PreviousControllerStates
        {
            get { return previousControllerStates; }
        }
    }
}
